home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / pilot-addresses.c.orig < prev    next >
Text File  |  1997-08-03  |  10KB  |  448 lines

  1. /* pilot-addresses.c:  Pilot address transfer utility
  2.  *
  3.  * This is free software, licensed under the GNU Public License V2.
  4.  * See the file COPYING for details.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "pi-source.h"
  10. #include "pi-socket.h"
  11. #include "pi-dlp.h"
  12. #include "pi-address.h"
  13.  
  14. /* Yet more hair: reorganize fields to match visible appearence */
  15.  
  16. int realentry[19] =   { 0, 1, 13, 2, 
  17.                         3, 4, 5, 6, 7, 
  18.                         8, 9, 10, 11, 12,
  19.                         14, 15, 16, 17,
  20.                         18 };
  21.  
  22. int encodechars = 0;
  23.  
  24. int inchar(FILE *in) {
  25.   int c;
  26.  
  27.   c = getc(in);
  28.   if (encodechars && c == '\\') {
  29.     c = getc(in);
  30.     switch(c) {
  31.       case 'b':                 c = '\b';  break;
  32.       case 'f':                 c = '\f';  break;
  33.       case 'n':                 c = '\n';  break;
  34.       case 't':                 c = '\t';  break;
  35.       case 'r':                 c = '\r';  break;
  36.       case 'v':                 c = '\v';  break;
  37.       case '\\':                c = '\\';  break;
  38.       default:  ungetc(c, in);  c = '\\';  break;
  39.     }
  40.   }
  41.   return c;
  42. }
  43.     
  44.  
  45. int read_field(char * dest, FILE * in) {
  46.   int c;
  47.   
  48.   do { /* Absorb whitespace */
  49.      c = getc(in);
  50.   } while ((c != EOF) && ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')));
  51.   
  52.   if (c == '"') {
  53.     c = inchar(in);
  54.     
  55.     while (c != EOF) {
  56.       if (c == '"') {
  57.         c = inchar(in);
  58.         if (c != '"')
  59.           break;
  60.       }
  61.       *dest++ = c;
  62.       c = inchar(in);
  63.     }
  64.   } else {
  65.     while (c != EOF) {
  66.       if (c == ',') {
  67.           break;
  68.       }
  69.       *dest++ = c;
  70.       c = inchar(in);
  71.     }
  72.   }
  73.   *dest++ = '\0';
  74.   
  75.   while ( (c != EOF)  && ( (c==' ')||(c=='\t') ) ) /* Absorb whitespace */
  76.     c = getc(in);
  77.     
  78.   if (c == ',')
  79.     return 1;
  80.   else if (c == ';')
  81.     return 2;
  82.   else if (c == EOF)
  83.     return -1; /* No more */
  84.   else
  85.     return 0;
  86. }
  87.  
  88. void outchar(char c, FILE *out) {
  89.  
  90.   if (encodechars) {
  91.     switch(c) {
  92.       case '"':   putc('"',  out);   putc('"',  out);  break;
  93.       case '\b':  putc('\\', out);   putc('b',  out);  break;
  94.       case '\f':  putc('\\', out);   putc('f',  out);  break;
  95.       case '\n':  putc('\\', out);   putc('n',  out);  break;
  96.       case '\t':  putc('\\', out);   putc('t',  out);  break;
  97.       case '\r':  putc('\\', out);   putc('r',  out);  break;
  98.       case '\v':  putc('\\', out);   putc('v',  out);  break;
  99.       case '\\':  putc('\\', out);   putc('\\', out);  break;
  100.       default:    putc(c, out);                        break;
  101.     }
  102.   }
  103.   else {
  104.     putc(c, out);
  105.     if (c == '"')
  106.       putc('"', out);
  107.   }
  108. }
  109.  
  110. int write_field(FILE * out, char * source, int more) {
  111.  
  112.   putc('"', out);
  113.   while (*source) {
  114.     outchar(*source, out);
  115.     source++;
  116.   }
  117.   putc('"',out);
  118.   
  119.   if (more==1)
  120.     putc(',',out);
  121.   else if (more==2)
  122.     putc(';',out);
  123.   else if (more==0)
  124.     putc('\n',out);
  125.   
  126.   return 0;
  127. }
  128.  
  129. int match_category(char * buf, struct AddressAppInfo * aai)
  130. {
  131.   int i;
  132.   for (i=0;i<16;i++)
  133.     if (strcasecmp(buf, aai->category.name[i])==0)
  134.       return i;
  135.   return atoi(buf); /* 0 is default */
  136. }
  137.  
  138. int match_phone(char * buf, struct AddressAppInfo * aai)
  139. {
  140.   int i;
  141.   for (i=0;i<8;i++)
  142.     if (strcasecmp(buf, aai->phoneLabels[i])==0)
  143.       return i;
  144.   return atoi(buf); /* 0 is default */
  145. }
  146.  
  147. int defaultcategory = 0;
  148.  
  149. int read_file(FILE * in, int sd, int db, struct AddressAppInfo * aai)
  150. {
  151.   struct Address a;
  152.   int i,l;
  153.   char buf[0xffff];
  154.   int category,attribute;
  155.  
  156.   do {
  157.     i = read_field(buf,in);
  158.  
  159.     memset(&a,0,sizeof(a));
  160.     a.showPhone = 0;
  161.     
  162.     if (i==2) {
  163.       category = match_category(buf, aai);
  164.       i = read_field(buf, in);
  165.       if (i==2) {
  166.         a.showPhone = match_phone(buf, aai);
  167.         i = read_field(buf, in);
  168.       }
  169.     } else
  170.       category = defaultcategory;
  171.     
  172.     if (i<0)
  173.       break;
  174.  
  175.     attribute = 0;
  176.     
  177.     for (l=0; (i>=0) && (l<19) ;l++) {
  178.       int l2 = realentry[l];
  179.  
  180.       if ( (l2>=3) && (l2<=7) ) {
  181.         if (i != 2)
  182.           a.phoneLabel[l2-3] = l2-3;
  183.         else {
  184.           a.phoneLabel[l2-3] = match_phone(buf, aai);
  185.           i = read_field(buf, in);
  186.         }
  187.       }
  188.       
  189.       a.entry[l2] = strdup(buf);
  190.       
  191.       if (i==0)
  192.         break;
  193.         
  194.       i = read_field(buf, in);
  195.     }
  196.     
  197.     attribute = (atoi(buf) ? dlpRecAttrSecret : 0);
  198.     
  199.     while (i > 0) { /* Too many fields in record */
  200.       i = read_field(buf, in);
  201.     }
  202.  
  203. #ifdef DEBUG    
  204.     printf("Category %s (%d)\n", aai->CategoryName[category], category);
  205.     for (l=0;l<19;l++) {
  206.       if ((l>=3) && (l<=7))
  207.         printf(" %s (%d): %s\n", aai->phoneLabels[a.phoneLabel[l-3]], a.phoneLabel[l-3], a.entry[l]);
  208.       else
  209.         printf(" %s: %s\n", aai->labels[l], a.entry[l]);
  210.     }
  211. #endif
  212.  
  213.     l = pack_Address(&a, (unsigned char *)buf, sizeof(buf));
  214. #ifdef DEBUG
  215.     dumpdata(buf,l);
  216. #endif    
  217.     dlp_WriteRecord(sd, db, attribute, 0, category, (unsigned char *)buf, l, 0);
  218.     
  219.   } while(i >= 0);
  220.   
  221.   return 0;
  222. }
  223.  
  224. int augment = 0;
  225.  
  226. int write_file(FILE * out, int sd, int db, struct AddressAppInfo * aai)
  227. {
  228.   struct Address a;
  229.   int i,j,l;
  230.   char buf[0xffff];
  231.   int category,attribute;
  232.   
  233.   for(i=0;
  234.       (j=dlp_ReadRecordByIndex(sd, db, i, (unsigned char *)buf, 0, &l, &attribute, &category))>=0;
  235.       i++)
  236.       {
  237.     if (attribute & dlpRecAttrDeleted)
  238.       continue;
  239.     unpack_Address(&a, (unsigned char *)buf, l);
  240.  
  241. /* Simplified system */
  242. #if 0    
  243.     write_field(out, "Category", 1);
  244.     write_field(out, aai->CategoryName[category],-1);
  245.     
  246.     for (j=0;j<19;j++) {
  247.       if (a.entry[j]) {
  248.         putc(',',out);
  249.         putc('\n',out);
  250.         if ( (j>=4) && (j<=8) )
  251.           write_field(out, aai->phoneLabels[a.phoneLabel[j-4]], 1);
  252.         else
  253.           write_field(out, aai->labels[j], 1);
  254.         write_field(out, a.entry[j], -1);
  255.       }
  256.     }
  257.     putc('\n',out);
  258. #endif
  259.     
  260. /* Complex system */
  261. #if 1
  262.     if (augment && (category || a.showPhone)) {
  263.       write_field(out,aai->category.name[category],2);
  264.       if (a.showPhone) {
  265.         write_field(out,aai->phoneLabels[a.showPhone],2);
  266.       }
  267.     }
  268.  
  269.     for (j=0;j<19;j++) {
  270. #ifdef NOT_ALL_LABELS
  271.       if (augment && (j >= 4) && (j<=8))
  272.         if (a.phoneLabel[j-4] != j-4)
  273.           write_field(out, aai->phoneLabels[a.phoneLabel[j-4]], 2);
  274.       if (a.entry[realentry[j]])
  275.         write_field(out, a.entry[realentry[j]], 1);
  276.  
  277. #else  /* print the phone labels if there is something in the field */
  278.       if (a.entry[realentry[j]]) {
  279.     if (augment && (j >= 4) && (j<=8))
  280.       write_field(out, aai->phoneLabels[a.phoneLabel[j-4]], 2);
  281.         write_field(out, a.entry[realentry[j]], 1);
  282.       }
  283. #endif
  284.       else
  285.         write_field(out, "", 1);
  286.     }
  287.     
  288.     sprintf(buf, "%d", (attribute & dlpRecAttrSecret) ? 1 : 0);
  289.     write_field(out, buf, 0);
  290.     
  291. #endif
  292.   }
  293.   
  294.   return 0;
  295. }
  296.  
  297. char * progname;
  298.  
  299. void Help(void)
  300. {
  301.   fprintf(stderr,"usage:%s %s [-c category] [-d category] [-a] [-e] -r|-w file\n",progname,TTYPrompt);
  302.   exit(2);
  303. }
  304.  
  305. int main(int argc, char *argv[])
  306. {
  307.   struct pi_sockaddr addr;
  308.   int db;
  309.   int sd;
  310.   int l;
  311.   struct PilotUser U;
  312.   int ret;
  313.   char buf[0xffff];
  314.   struct AddressAppInfo aai;
  315.   char * defaultcategoryname = 0;
  316.   char * deletecategory = 0;
  317.   int mode = 0;
  318.   int c;
  319.   extern char* optarg;
  320.   extern int optind;
  321.  
  322.   progname = argv[0];
  323.  
  324.   if (argc < 4)
  325.     Help();
  326.  
  327.   optind = 2;
  328.   while (((c = getopt(argc, argv, "ed:c:arw")) != -1) && (mode == 0)) {
  329.     switch (c) {
  330.     case 'a':
  331.       augment = 1;
  332.       break;
  333.     case 'd':
  334.       deletecategory = optarg;
  335.       break;
  336.     case 'e':
  337.       encodechars = 1;
  338.       break;
  339.     case 'c':
  340.       defaultcategoryname = optarg;
  341.       break;
  342.     case 'r':
  343.       mode = 1;
  344.       break;
  345.     case 'w':
  346.       mode = 2;
  347.       break;
  348.     case 'h': case '?':
  349.       Help();
  350.     }
  351.   }
  352.   
  353.   if (mode == 0)
  354.     Help();
  355.   
  356.   if (!(sd = pi_socket(PI_AF_SLP, PI_SOCK_STREAM, PI_PF_PADP))) {
  357.     perror("pi_socket");
  358.     exit(1);
  359.   }
  360.     
  361.   addr.pi_family = PI_AF_SLP;
  362.   strcpy(addr.pi_device,argv[1]);
  363.   
  364.   ret = pi_bind(sd, (struct sockaddr*)&addr, sizeof(addr));
  365.   if(ret == -1) {
  366.     perror("pi_bind");
  367.     exit(1);
  368.   }
  369.  
  370.   ret = pi_listen(sd,1);
  371.   if(ret == -1) {
  372.     perror("pi_listen");
  373.     exit(1);
  374.   }
  375.  
  376.   sd = pi_accept(sd, 0, 0);
  377.   if(sd == -1) {
  378.     perror("pi_accept");
  379.     exit(1);
  380.   }
  381.  
  382.   /* Ask the pilot who it is. */
  383.   dlp_ReadUserInfo(sd,&U);
  384.   
  385.   /* Tell user (via Pilot) that we are starting things up */
  386.   dlp_OpenConduit(sd);
  387.   
  388.   /* Open the Memo Pad's database, store access handle in db */
  389.   if(dlp_OpenDB(sd, 0, 0x80|0x40, "AddressDB", &db) < 0) {
  390.     puts("Unable to open AddressDB");
  391.     dlp_AddSyncLogEntry(sd, "Unable to open AddressDB.\n");
  392.     exit(1);
  393.   }
  394.   
  395.   l = dlp_ReadAppBlock(sd, db, 0, (unsigned char *)buf, 0xffff);
  396.   unpack_AddressAppInfo(&aai, (unsigned char *)buf, l);
  397.  
  398.   if (defaultcategoryname)
  399.     defaultcategory = match_category(defaultcategoryname,&aai);
  400.   else
  401.     defaultcategory = 0; /* Unfiled */
  402.  
  403.   if (mode == 2) { /* Write */
  404.     FILE * f = fopen(argv[optind],"w");
  405.     if (f == NULL) {
  406.       sprintf(buf, "%s: %s", argv[0], argv[optind]);
  407.       perror(buf);
  408.       exit(1);
  409.     }
  410.     write_file(f, sd, db, &aai);
  411.     if (deletecategory) 
  412.       dlp_DeleteCategory(sd, db, match_category(deletecategory,&aai));
  413.     fclose(f);
  414.   } else if (mode == 1) {
  415.     FILE * f;
  416.     while(optind < argc) {
  417.       f = fopen(argv[optind],"r");
  418.       if (f == NULL) {
  419.         sprintf(buf, "%s: %s", argv[0], argv[optind]);
  420.         perror(buf);
  421.         continue;
  422.       }
  423.       if (deletecategory) 
  424.         dlp_DeleteCategory(sd, db, match_category(deletecategory,&aai));
  425.       read_file(f, sd, db, &aai);
  426.       fclose(f);
  427.       optind++;
  428.     }
  429.   }
  430.   
  431.   /* Close the database */
  432.   dlp_CloseDB(sd, db);
  433.  
  434.   /* Tell the user who it is, with a different PC id. */
  435.   U.lastSyncPC = 0xDEADBEEF;
  436.   U.successfulSyncDate = time(NULL);
  437.   U.lastSyncDate = U.successfulSyncDate;
  438.   dlp_WriteUserInfo(sd,&U);
  439.  
  440.   dlp_AddSyncLogEntry(sd, "Wrote addresses to Pilot.\n");
  441.   
  442.   /* All of the following code is now unnecessary, but harmless */
  443.   
  444.   dlp_EndOfSync(sd,0);
  445.   pi_close(sd);
  446.   exit(0);
  447. }
  448.